package com.fzk.blog.settings.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fzk.blog.bean.DicType;
import com.fzk.blog.bean.DicValue;
import com.fzk.blog.bean.vo.DicInfo;
import com.fzk.blog.blog.service.IRedisService;
import com.fzk.blog.exception.MyException;
import com.fzk.blog.mapper.DicTypeMapper;
import com.fzk.blog.mapper.DicValueMapper;
import com.fzk.blog.settings.service.IDicService;
import com.fzk.blog.utils.MyJsonUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;

/**
 * @author fzk
 * @date 2021-08-19 22:37
 */
@Service
public class DicService implements IDicService {
    @Resource
    private DicTypeMapper dicTypeMapper;
    @Resource
    private DicValueMapper dicValueMapper;
    @Resource
    private IRedisService redisService;

    @Override
    public List<DicInfo> getDicInfoList() throws JsonProcessingException {
        List<DicInfo> dicInfoList = null;
        // 1.去redis 拿
        String json = redisService.get("dicInfoList");
        // 2.没有则数据库查，并放入redis
        if (json != null)
            dicInfoList = MyJsonUtil.toBeanArray(json, DicInfo.class);
        else {
            dicInfoList = dicTypeMapper.getDicInfoList();
            redisService.setEx("dicInfoList", MyJsonUtil.writeToString(dicInfoList));
        }
        return dicInfoList;
    }

    @Override
    public List<DicInfo> getDicInfoByTypeId(int dicTypeId) {
        List<DicInfo> dicInfoList = new LinkedList<>();
        // 1.去redis 拿
        String json = redisService.get("dicInfoList");
        // 2.没有则数据库查，但是不放入redis
        if (json != null) {
            List<DicInfo> dicInfos = MyJsonUtil.toBeanArray(json, DicInfo.class);
            // 从这里面选择需要的
            for (DicInfo dicInfo : dicInfos) {
                if (dicInfo.getDicTypeId().equals(dicTypeId))
                    dicInfoList.add(dicInfo);
            }

        } else {
            dicInfoList = dicTypeMapper.getDicInfoByTypeId(dicTypeId);
        }
        return dicInfoList;
    }

    @Override
    public List<DicInfo> getDicInfoByTypeName(String dicTypeName) {
        List<DicInfo> dicInfoList = new LinkedList<>();
        // 1.去redis 拿
        String json = redisService.get("dicInfoList");
        // 2.没有则数据库查，但是不放入redis
        if (json != null) {
            List<DicInfo> dicInfos = MyJsonUtil.toBeanArray(json, DicInfo.class);
            // 从这里面选择需要的
            for (DicInfo dicInfo : dicInfos) {
                if (dicInfo.getDicTypeName().equals(dicTypeName))
                    dicInfoList.add(dicInfo);
            }
        } else
            dicInfoList = dicTypeMapper.getDicInfoByTypeName(dicTypeName);

        if (dicInfoList.size() == 0)
            throw new MyException(400, "参数错误，dic_type_name不存在：" + dicTypeName);

        return dicInfoList;
    }

    @Override
    @Transactional//开事务
    public List<DicInfo> insertDicType(DicType dicType, int loginId) {
        // 1.完善插入数据
        dicType.setCreateBy(loginId);
        dicType.setEditBy(loginId);
        dicType.setFlag(0);

        // 2.检查是否有相同的name
        List<DicType> dicTypes = dicTypeMapper.selectByName(dicType.getName());
        if (dicTypes.size() != 0)
            throw new MyException(400, "数据字典类型名：" + dicType.getName() + " 已经存在");

        // 3.插入
        int insert = dicTypeMapper.insert(dicType);
        if (insert != 1)
            throw new MyException(400, "插入失败");

        // 4.清redis的dicInfoList和dicTypeList
        redisService.delete("dicInfoList", "dicTypeList");

        // 5,查info
        return dicTypeMapper.getDicInfoByTypeId(dicType.getId());
    }

    @Override
    @Transactional//开事务
    public List<DicInfo> updateDicType(DicType dicType, int loginId) {
        //  1.完善更新数据
        dicType.setEditBy(loginId);

        // 2.检查是否已经存在name了
        List<DicType> dicTypes = dicTypeMapper.selectByName(dicType.getName());
        if (dicTypes.size() != 0 && !dicTypes.get(0).getId().equals(dicType.getId()))
            throw new MyException(400, "数据字典类型名：" + dicType.getName() + " 已经存在");

        // 3.更新
        int i = dicTypeMapper.updateById(dicType);
        if (i != 1)
            throw new MyException(500, "更新失败，id：" + dicType.getId());

        // 4.清redis的dicInfoList和dicTypeList和dicType:id:xx
        redisService.delete("dicInfoList", "dicTypeList", "dicType:id:" + dicType.getId());

        // 5,查info
        return dicTypeMapper.getDicInfoByTypeId(dicType.getId());
    }

    @Override
    @Transactional//开事务
    public List<DicInfo> deleteDicType(int id, int loginId) {
        // 1.查info
        List<DicInfo> dicInfoList = dicTypeMapper.getDicInfoByTypeId(id);

        // 2.删除字典类型
        int i = dicTypeMapper.deleteById(id);
        if (i != 1)
            throw new MyException(500, "删除失败：id：" + id);

        //3. 删除字典值
        int j = dicValueMapper.logicalDeleteByTypeId(id, loginId);
        int j_confirm = 0;
        if (dicInfoList.get(0).getDicValueId() != null)
            j_confirm = dicInfoList.size();
        if (j != j_confirm)
            throw new MyException(500, "删除失败：id：" + id);

        // 4.清redis的dicInfoList和dicTypeList和dicType:id:xx
        redisService.delete("dicInfoList", "dicTypeList", "dicType:id:" + id);

        return dicInfoList;
    }

    @Override
    @Transactional//开事务
    public List<DicInfo> insertDicValue(DicValue dicValue, int loginId) {
        // 1.完善插入数据
        dicValue.setCreateBy(loginId);
        dicValue.setEditBy(loginId);
        dicValue.setFlag(0);

        // 2.检查是否有相同的name
        List<DicValue> dicValues = dicValueMapper.selectByName(dicValue.getName(), dicValue.getDicTypeId());
        if (dicValues.size() != 0)
            throw new MyException(400, "此数据字典类型下的数据字典值名：" + dicValue.getName() + " 已经存在");

        // 3.插入
        int insert = dicValueMapper.insert(dicValue);
        if (insert != 1)
            throw new MyException(400, "插入失败");

        // 4.清redis的dicInfoList
        redisService.delete("dicInfoList");

        // 5,查info
        return dicTypeMapper.getDicInfoByTypeId(dicValue.getDicTypeId());
    }

    @Override
    @Transactional//开事务
    public void updateDicValue(DicValue dicValue, int loginId) {
        //  1.完善更新数据
        dicValue.setEditBy(loginId);

        // 2.检查是否有相同的name
        List<DicValue> dicValues = dicValueMapper.selectByName(dicValue.getName(), dicValueMapper.selectById(dicValue.getId()).getDicTypeId());
        if (dicValues.size() != 0 && !dicValues.get(0).getId().equals(dicValue.getId()))
            throw new MyException(400, "此数据字典类型下的数据字典值名：" + dicValue.getName() + " 已经存在");

        // 3.更新
        int i = dicValueMapper.updateById(dicValue);
        if (i != 1)
            throw new MyException(500, "更新失败，id：" + dicValue.getId());

        // 4.清redis的dicInfoList
        redisService.delete("dicInfoList");
    }

    @Override
    @Transactional//开事务
    public void deleteDicValue(int id, int loginId) {
        int i = dicValueMapper.logicalDeleteById(id, loginId);
        if (i != 1)
            throw new MyException(500, "删除失败：id：" + id);
        // 清redis的dicInfoList
        redisService.delete("dicInfoList");
    }

    @Override
    public List<DicType> getDicTypeList() throws JsonProcessingException {
        List<DicType> dicTypeList = null;
        // 1.去redis 拿
        String json = redisService.get("dicTypeList");
        // 2.没有则数据库查，并放入redis
        if (json != null)
            dicTypeList = MyJsonUtil.toBeanArray(json, DicType.class);
        else {
            dicTypeList = dicTypeMapper.selectList(null);
            redisService.setEx("dicTypeList", MyJsonUtil.writeToString(dicTypeList));
        }
        return dicTypeList;
    }

    @Override
    public DicType getDicType(int typeId) throws JsonProcessingException {
        DicType dicType = null;
        // 1.去 redis 拿
        String json = redisService.get("dicType:id:" + typeId);
        // 2.没有则数据库查，并放入redis
        if (json != null)
            dicType = MyJsonUtil.toBean(json, DicType.class);
        else {
            dicType = dicTypeMapper.selectById(typeId);
            if (dicType == null)
                throw new MyException(400, "id不存在：" + typeId);
            redisService.setEx("dicType:id:" + typeId, MyJsonUtil.writeToString(dicType));
        }
        return dicType;
    }

}
